package com.ywt.cda.resolver;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Enumeration;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.supply.network.melody.common.web.url.StampURLBroker;
import com.supply.network.melody.common.web.url.URLBroker;
import com.ywt.cda.access.AccessDeniedException;
import com.ywt.cda.domain.UserAgent;

public class MelodyExceptionResolver implements HandlerExceptionResolver {
	private static final Log logger = LogFactory
			.getLog(MelodyExceptionResolver.class);

	private String webEncoding = "UTF-8";

	private String errorPage = "/error";

	private String loginPath = "/login.htm";

	private String deniedPage = "/admin/accessDenied";

	private String loginReturnParameterName = "backto";
	
	@Resource
	private URLBroker appServerBroker;
	
	@Resource
	private StampURLBroker imageServerBroker;

	public void setWebEncoding(String webEncoding) {
		this.webEncoding = webEncoding;
	}

	public void setErrorPage(String errorPage) {
		this.errorPage = errorPage;
	}

	public void setLoginPath(String loginPath) {
		this.loginPath = loginPath;
	}

	public void setDeniedPage(String deniedPage) {
		this.deniedPage = deniedPage;
	}

	public void setLoginReturnParameterName(
			String loginReturnParameterName) {
		this.loginReturnParameterName = loginReturnParameterName;
	}

	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		if (ex instanceof AccessDeniedException) {
			return resolveAccessDeniedException(request);
		}
		logger.error("web error", ex);
		return new ModelAndView(this.errorPage);
	}

	private ModelAndView resolveAccessDeniedException(HttpServletRequest request) {
		UserAgent agent = (UserAgent) request.getAttribute(UserAgent.USER_AGENT_IN_REQUEST);
		if (agent.getAppId() == null || agent.getLoginName() == null) {// 没登录，定向到登录界面
			String returnUrl = getReturnUrl(request);
			return new ModelAndView("redirect:" + loginPath,
					loginReturnParameterName, returnUrl);
		}
		request.setAttribute("appServer", appServerBroker);
		request.setAttribute("imageServer", imageServerBroker);
		return new ModelAndView(this.deniedPage);
	}

	private String getReturnUrl(HttpServletRequest request) {
		StringBuffer sb = request.getRequestURL();
		appendRequestParameters(sb, request);
		try {
			return URLEncoder.encode(sb.toString(), this.webEncoding);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	private void appendRequestParameters(StringBuffer sb,
			HttpServletRequest request) {
		Enumeration en = request.getParameterNames();
		if (!en.hasMoreElements()) {
			return;
		}
		sb.append('?');
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			String[] values = request.getParameterValues(name);
			if (values == null || values.length == 0) {
				continue;
			}
			for (String v : values) {
				try {
					v = URLEncoder.encode(v, this.webEncoding);
				} catch (UnsupportedEncodingException ignore) {
				}
				sb.append(name).append('=').append(v).append('&');
			}
		}
		sb.deleteCharAt(sb.length() - 1);
	}
}
